﻿Public Class MySecurity
    'Classe maison qui contient la sécurité d'un dossier ou d'un fichier
    Private Path As String
    Private sAccessRules As String
    Private colAccessRules As System.Collections.Generic.SortedDictionary(Of String, MyFileSystemAccessRule)

    Public Sub New(ByVal sPath As String)
        Try
            Me.Path = sPath
            'Initialiser la collection des objets MyFileAccessRules
            Me.colAccessRules = New System.Collections.Generic.SortedDictionary(Of String, MyFileSystemAccessRule)
            'On va avoir besoin de deux objets distincts pour fusionner les règles d'accès FileSystemAccessRule
            'car il peut y en avoir plusieurs différentes pour une même identité...
            Dim oMyFileSystemAccessRule, oNew As MyFileSystemAccessRule
            'Obtenons la sécurité du fichier
            Dim oAccessControl As Object = Me.GetAccessControl(sPath)
            If Not oAccessControl Is Nothing Then
                'Ok, on a obtenu quelque-chose.
                'Traitons toutes les règles d'accès et cumulons les par identité distinctes
                For Each oAR As System.Security.AccessControl.FileSystemAccessRule In oAccessControl.GetAccessRules(True, True, GetType(System.Security.Principal.NTAccount))
                    'Créer une nouvelle règle d'accès maison à partir de la règle obtenue
                    oNew = New MyFileSystemAccessRule(oAR)
                    'On la fusionne si on a déjà une règle pour la même identité
                    If Me.colAccessRules.ContainsKey(oNew.Key) Then
                        'On récupère la règle déjà définie
                        oMyFileSystemAccessRule = Me.colAccessRules.Item(oNew.Key)
                        'On merge les droits du nouvel objet
                        oMyFileSystemAccessRule.FileSystemRights = oMyFileSystemAccessRule.FileSystemRights Or oNew.FileSystemRights
                    Else
                        'On conserve la règle pour la nouvelle identité
                        Me.colAccessRules.Add(oNew.Key, oNew)
                    End If
                Next 'On passe à la règle suivante
                'On a maintenant des règles uniques pour chaque identité.
            End If
            Trace.Unindent()
        Catch Ex As Exception
            Trace.WriteLine("** Exception " & Ex.Message)
            Trace.Unindent()
        End Try
    End Sub

    Public Function StringValue(ByVal BasicRightsOnly As Boolean) As String
        'Retourne une chaine descriptive de la sécurité complète
        Dim sDroits As String = ""
        sDroits &= "<html><head><style type=""text/css"">" & vbCrLf
        sDroits &= "<!--.Titre {font-size: medium;color: #FFFFFF; background-color: #0066FF}-->" & vbCrLf
        sDroits &= "<!--.Style1 {font-size: x-small;color: #003366}-->" & vbCrLf
        sDroits &= "<!--.Style2 {font-size: xx-small}-->" & vbCrLf
        sDroits &= "</style></head>"
        sDroits &= "<p class=""Titre"">Accès au fichier " & Me.Path & "</p>"
        sDroits &= "<table>"
        Dim sDroit As String
        'On va cumuler les descriptif de sécurité de chaque identité
        For Each oMyFileSystemAccessRule As MyFileSystemAccessRule In Me.colAccessRules.Values
            sDroit = oMyFileSystemAccessRule.StringValue(BasicRightsOnly)
            'On n'affiche que les droits effectifs
            If sDroit <> "" Then sDroits &= sDroit
        Next
        sDroits &= "</table></html>"
        Return sDroits
    End Function

    Private Function GetAccessControl(ByVal sPath) As Object
        'Obtenir un access control pour l'objet spécifié.
        If My.Computer.FileSystem.FileExists(sPath) Then
            Dim oFile As New System.IO.FileInfo(sPath)
            Return oFile.GetAccessControl()
        Else
            Return Nothing
        End If
    End Function

    Public Function GetLegende(ByVal BasicRightsOnly As Boolean) As String
        'Obtenir la légende des abbréviations des noms des droits d'accès
        'Le contenu diffère selon l'option ShowExtended...

        Dim sAide As String = "<p><b>Legende:</b></p><font size=""small""><table>"
        Dim iLast As Integer = 0
        Dim sSymbole As String = ""
        Dim sSymboleCourt As String = ""
        For Each iValue As Integer In [Enum].GetValues(GetType(System.Security.AccessControl.FileSystemRights))
            If (iValue <> iLast) And ((Array.IndexOf(BasicRights, iValue) <> -1) Or (Not BasicRightsOnly)) Then
                'On traite les droits basic seulement ou les droits avancés ?
                sSymbole = System.Enum.GetName(GetType(System.Security.AccessControl.FileSystemRights), iValue)
                sSymboleCourt = GetShortName(sSymbole)
                sAide &= "<tr class=""Style2""><td>" & sSymboleCourt & "</td><td>" & sSymbole & "</td></tr>" & vbCrLf
                'sAide = AppendString(sAide, sSymboleCourt & " : " & sSymbole, vbCrLf)
                iLast = iValue
            End If
        Next
        'sAide = Commun.Indent(sAide, 2)
        'sAide = Commun.Aligner(sAide, ":")
        'sAide = AppendString("Legende : ", sAide, vbCrLf)
        sAide &= "</font></table>"
        Return sAide
    End Function
End Class
